package cn.edu.tju.core.security.rest;

import cn.edu.tju.core.model.Authority;
import cn.edu.tju.core.model.HttpResult;
import cn.edu.tju.core.model.Person;
import cn.edu.tju.core.security.SecurityUtils;
import cn.edu.tju.core.security.UserModelDetailsService;
import cn.edu.tju.core.security.repository.PersonRepository;
import org.springframework.security.access.prepost.PreAuthorize;
import cn.edu.tju.core.security.repository.UserRepository;
import cn.edu.tju.core.security.rest.dto.LoginDto;
import cn.edu.tju.core.security.rest.dto.RegisterDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import cn.edu.tju.core.model.User;
import cn.edu.tju.core.security.service.UserService;
import cn.edu.tju.core.model.ResultCodeEnum;
import cn.edu.tju.elm.repository.BusinessApplicationRepository;
import cn.edu.tju.elm.repository.BusinessRepository;
import cn.edu.tju.elm.repository.OrderRepository;

import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
import java.util.List;
import java.util.Optional;

import java.util.HashSet;
import java.time.LocalDateTime;
import java.util.Set;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api")
@Tag(name = "管理用户", description = "提供用户的增删改查操作")
public class UserRestController {

   private final UserService userService;
   private final PersonRepository personRepository;
   private final BusinessApplicationRepository businessApplicationRepository;
   private final BusinessRepository businessRepository;
   private final UserModelDetailsService userModelDetailsService;
   private final UserRepository userRepository;
   private final OrderRepository orderRepository;

   public UserRestController(UserService userService,
                             PersonRepository personRepository,
                             UserModelDetailsService userModelDetailsService,
                             UserRepository userRepository,
                             BusinessApplicationRepository businessApplicationRepository,
                             BusinessRepository businessRepository,
                             OrderRepository orderRepository) {
      this.userService = userService;
      this.personRepository = personRepository;
      this.userModelDetailsService = userModelDetailsService;
      this.userRepository = userRepository;
      this.businessApplicationRepository = businessApplicationRepository;
      this.businessRepository = businessRepository;
      this.orderRepository = orderRepository;
   }

   @PostMapping("/users")
   @Operation(summary = "新增用户（仅登录帐号）", description = "创建一个新的用户（仅登录帐号）")
   public ResponseEntity<User> createUser(@RequestBody User newUser) {
      User user = userService.getUserWithAuthorities().get();
      LocalDateTime now = LocalDateTime.now();
      newUser.setCreator(user.getId());
      newUser.setCreateTime(now);
      newUser.setUpdater(user.getId());
      newUser.setUpdateTime(now);
      newUser.setDeleted(false);
      newUser.setPassword(SecurityUtils.BCryptPasswordEncode("password"));
      newUser.setActivated(true);
      User user1 = userService.addUser(newUser);
      return ResponseEntity.ok(user1);
   }

   @GetMapping("/user")
   @Operation(summary = "判断当前登录的用户", description = "判断当前登录的用户")
   public ResponseEntity<User> getActualUser() {
      return ResponseEntity.ok(userService.getUserWithAuthorities().get());
   }

   @PostMapping("/password")
   @Operation(summary = "修改密码", description = "已登录的用户只可以修改自己的密码，Admin可以修改任何人的密码")
   public ResponseEntity<String> updateUserPassword(@RequestBody LoginDto loginDto) {
      User me =  userService.getUserWithAuthorities().get();
      boolean isAdmin = false;
      for (Authority authority : me.getAuthorities()) {
         if (authority.getName().equals("ADMIN")) {
            isAdmin = true;
            break;
         }
      }
      User updateUser = userRepository.findOneWithAuthoritiesByUsername(loginDto.getUsername()).get();
      //userModelDetailsService.loadUserByUsername(loginDto.getUsername());
      if (me.getUsername().equals(loginDto.getUsername()) || isAdmin ) {
         updateUser.setPassword(SecurityUtils.BCryptPasswordEncode(loginDto.getPassword()));
         userService.updateUser(updateUser);
         return ResponseEntity.ok().body("Update the password successfully.");
      } else {
         return ResponseEntity.unprocessableEntity().body("Failed to update the password.");
      }
   }

   @PostMapping("/persons")
   @Operation(summary = "新增用户（自然人）", description = "创建一个新的用户（自然人）")
   public Person addPerson(@RequestBody Person person){
      User user = userService.getUserWithAuthorities().get();
      LocalDateTime now = LocalDateTime.now();
      person.setCreator(user.getId());
      person.setCreateTime(now);
      person.setUpdater(user.getId());
      person.setUpdateTime(now);
      person.setDeleted(false);
      person.setPassword(SecurityUtils.BCryptPasswordEncode("password"));
      person.setActivated(true);
      return personRepository.save(person);
   }

   @PostMapping("/register")
   @Operation(summary = "注册用户", description = "注册一个新用户")
   public HttpResult<String> register(@RequestBody @Valid RegisterDto registerDto) {
      try {
         // 检查用户名是否已存在
         if (userRepository.findOneByUsername(registerDto.getUsername()).isPresent()) {
            return HttpResult.failure(ResultCodeEnum.USERNAME_EXISTS);
         }

         // 创建新用户
         Person person = new Person();
         person.setUsername(registerDto.getUsername().trim());
         String password = registerDto.getPassword();
         if (password == null || password.trim().isEmpty()) password = "password"; // 默认密码
         person.setPassword(SecurityUtils.BCryptPasswordEncode(password));
         person.setFirstName(registerDto.getFirstName().trim());
         person.setLastName(registerDto.getLastName().trim());
         person.setEmail(registerDto.getEmail().trim().toLowerCase());
         person.setPhone(registerDto.getPhone() != null ? registerDto.getPhone().trim() : null);
         person.setGender(registerDto.getGender());
         person.setActivated(true);
         person.setDeleted(false);

         // 设置默认权限（USER）
         Set<Authority> authorities = new HashSet<>();
         Authority authority = new Authority();
         authority.setName("USER");
         authorities.add(authority);
         person.setAuthorities(authorities);

         // 设置创建时间和更新信息
         LocalDateTime now = LocalDateTime.now();
         person.setCreateTime(now);
         person.setUpdateTime(now);

         // 保存用户
         Person savedPerson = personRepository.save(person);

         if (savedPerson != null && savedPerson.getId() != null) {
            return HttpResult.success("用户注册成功");
         } else {
            return HttpResult.failure(ResultCodeEnum.REGISTRATION_FAILED);
         }

      } catch (Exception e) {
         return HttpResult.failure(ResultCodeEnum.SERVER_ERROR);
      }
   }


   @GetMapping("/persons/current")
   @Operation(summary = "查看个人信息", description = "获取当前登录用户的个人信息")
   public HttpResult<Person> getCurrentPerson() {
      try {
         Person person = userService.getCurrentPerson();
         return HttpResult.success(person);
      } catch (RuntimeException e) {
         return HttpResult.failure(ResultCodeEnum.USER_NOT_FOUND);
      } catch (Exception e) {
         return HttpResult.failure(ResultCodeEnum.SERVER_ERROR);
      }
   }

   @PutMapping("/persons/current")
   @Operation(summary = "修改个人信息", description = "修改当前登录用户的个人信息")
   public HttpResult<Person> updateCurrentPerson(@RequestBody Person updatedPerson) {
      try {
         Person savedPerson = userService.updateCurrentPerson(updatedPerson);
         return HttpResult.success(savedPerson);
      } catch (RuntimeException e) {
         return HttpResult.failure(ResultCodeEnum.USER_NOT_FOUND);
      } catch (Exception e) {
         return HttpResult.failure(ResultCodeEnum.SERVER_ERROR);
      }
   }

   //查看用户列表（管理员）
   @GetMapping("/admin/users")
   @PreAuthorize("hasAuthority('ADMIN')")
   @Operation(summary = "查看用户列表", description = "管理员查看所有用户列表")
   public ResponseEntity<List<User>> getAllUsers() {
      List<User> users = userService.findAllUsers();
      return ResponseEntity.ok(users);
   }

   //删除用户（管理员）
   @DeleteMapping("/admin/users/{id}")
   @PreAuthorize("hasAuthority('ADMIN')")
   @Operation(summary = "删除用户", description = "管理员删除指定ID的用户（软删除）")
   public ResponseEntity<String> deleteUser(@PathVariable Long id) {
      try {
         // 检查要删除的用户是否存在
         Optional<User> targetUserOptional = userRepository.findById(id);
         if (!targetUserOptional.isPresent()) {
            return ResponseEntity.notFound().build();
         }

         User targetUser = targetUserOptional.get();

         // 检查不能删除自己
         User currentUser = userService.getUserWithAuthorities().get();
         if (targetUser.getId().equals(currentUser.getId())) {
            return ResponseEntity.badRequest().body("不能删除自己的账户");
         }

         // 检查不能删除其他管理员（可选的安全限制）
         boolean isTargetAdmin = userService.hasAuthority(targetUser, "ADMIN");
         if (isTargetAdmin) {
            return ResponseEntity.badRequest().body("不能删除其他管理员账户");
         }

         // 执行软删除
         boolean deleted = userService.deleteUserById(id);
         if (deleted) {
            return ResponseEntity.ok("用户删除成功");
         } else {
            return ResponseEntity.notFound().build();
         }
      } catch (Exception e) {
         return ResponseEntity.internalServerError().body("删除用户失败: " + e.getMessage());
      }
   }

   //启用/禁用用户（管理员）
   @PutMapping("/admin/users/{id}/activation")
   @PreAuthorize("hasAuthority('ADMIN')")
   @Operation(summary = "启用/禁用用户", description = "管理员启用或禁用用户账户")
   public ResponseEntity<User> toggleUserActivation(@PathVariable Long id, @RequestParam Boolean activated) {
      try {
         Optional<User> userOptional = userRepository.findById(id);
         if (!userOptional.isPresent()) {
            return ResponseEntity.notFound().build();
         }

         User user = userOptional.get();
         user.setActivated(activated);
         user.setUpdateTime(LocalDateTime.now());

         // 设置更新者为当前用户
         User currentUser = userService.getUserWithAuthorities().get();
         user.setUpdater(currentUser.getId());

         User updatedUser = userService.updateUser(user);
         return ResponseEntity.ok(updatedUser);
      } catch (Exception e) {
         return ResponseEntity.internalServerError().build();
      }
   }

   @GetMapping("/admin/stats/total-users")
   @PreAuthorize("hasAuthority('ADMIN')")
   @Operation(summary = "获取用户总数", description = "管理员获取用户总数")
   public HttpResult<Long> getTotalUsers() {
      try {
         long totalUsers = userRepository.countByDeletedFalse();
         return HttpResult.success(totalUsers);
      } catch (Exception e) {
         return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "获取用户总数失败");
      }
   }

   @GetMapping("/admin/stats/pending-applications")
   @PreAuthorize("hasAuthority('ADMIN')")
   @Operation(summary = "获取待审核申请数", description = "管理员获取待审核的开店申请数")
   public HttpResult<Long> getPendingApplications() {
      try {
         long pendingApplications = businessApplicationRepository.countByStatus(0);
         return HttpResult.success(pendingApplications);
      } catch (Exception e) {
         return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "获取待审核申请数失败");
      }
   }

   @GetMapping("/admin/stats/total-businesses")
   @PreAuthorize("hasAuthority('ADMIN')")
   @Operation(summary = "获取店铺总数", description = "管理员获取店铺总数")
   public HttpResult<Long> getTotalBusinesses() {
      try {
         long totalBusinesses = businessRepository.countByDeletedFalse();
         return HttpResult.success(totalBusinesses);
      } catch (Exception e) {
         return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "获取店铺总数失败");
      }
   }

   @GetMapping("/admin/stats/total-orders")
   @PreAuthorize("hasAuthority('ADMIN')")
   @Operation(summary = "获取订单总数", description = "管理员获取订单总数")
   public HttpResult<Long> getTotalOrders() {
      try {
         long totalOrders = orderRepository.countByDeletedFalse();
         return HttpResult.success(totalOrders);
      } catch (Exception e) {
         return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "获取订单总数失败");
      }
   }

}
